package com.example.demo2;

import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import com.google.android.gms.location.Priority;
import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.location.Location;
import android.location.LocationManager;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.provider.Settings;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.google.android.gms.location.FusedLocationProviderClient;
import com.google.android.gms.location.LocationCallback;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationResult;
import com.google.android.gms.location.LocationServices;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;
import okhttp3.FormBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

public class MainActivity extends AppCompatActivity {

    private Button clickButton;
    private LinearLayout contentLayout;
    private FusedLocationProviderClient fusedLocationClient;
    private static final int LOCATION_PERMISSION_REQUEST_CODE = 1;
    private LocationCallback locationCallback;
    private Handler handler;
    private Runnable periodicLocationRunnable;
    private String deviceId;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // 获取设备唯一标识
        deviceId = Settings.Secure.getString(getContentResolver(), Settings.Secure.ANDROID_ID);

        // 初始化视图组件
        clickButton = findViewById(R.id.clickButton);
        contentLayout = findViewById(R.id.contentLayout);

        // 初始化定位客户端
        fusedLocationClient = LocationServices.getFusedLocationProviderClient(this);

        locationCallback = new LocationCallback() {
            @Override
            public void onLocationResult(LocationResult locationResult) {
                if (locationResult == null) {
                    Log.d("Location", "Location result is null");
                    return;
                }
                for (Location location : locationResult.getLocations()) {
                    if (location != null) {
                        // 将 WGS - 84 坐标转换为 BD - 09 坐标
                        double[] bd09Coords = wgs84ToBd09(location.getLatitude(), location.getLongitude());
                        String latitude = String.valueOf(bd09Coords[0]);
                        String longitude = String.valueOf(bd09Coords[1]);

                        // 创建一个新的 TextView 显示转换后的坐标和设备唯一标识
                        TextView textView = new TextView(MainActivity.this);
                        String locationText = "设备唯一标识: " + deviceId + "，纬度: " + latitude + ", 经度: " + longitude;
                        textView.setText(locationText);
                        // 将 TextView 添加到布局中
                        contentLayout.addView(textView);
                        Log.d("Location", "Location updated: " + locationText);

                        // 发送 POST 请求
                        sendPostRequest(deviceId, latitude, longitude);
                    }
                }
            }
        };

        // 设置按钮点击监听器
        clickButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 停止定时任务
                handler.removeCallbacks(periodicLocationRunnable);
                checkLocationAndRequest();
                // 重新启动定时任务
                handler.postDelayed(periodicLocationRunnable, 10000);
            }
        });

        handler = new Handler();
        periodicLocationRunnable = new Runnable() {
            @Override
            public void run() {
                checkLocationAndRequest();
                handler.postDelayed(this, 10000); // 每隔 10 秒执行一次
            }
        };
    }

    @Override
    protected void onResume() {
        super.onResume();
        // 开始定时任务
        handler.postDelayed(periodicLocationRunnable, 10000);
    }

    @Override
    protected void onPause() {
        super.onPause();
        // 停止定时任务
        handler.removeCallbacks(periodicLocationRunnable);
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == LOCATION_PERMISSION_REQUEST_CODE) {
            if (grantResults.length > 0 &&
                    grantResults[0] == PackageManager.PERMISSION_GRANTED &&
                    grantResults[1] == PackageManager.PERMISSION_GRANTED) {
                // 权限已授予，再次尝试获取位置
                requestLocationUpdates();
            } else {
                // 权限被拒绝
                TextView textView = new TextView(MainActivity.this);
                textView.setText("定位权限被拒绝，无法获取位置信息");
                contentLayout.addView(textView);
            }
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (fusedLocationClient != null) {
            fusedLocationClient.removeLocationUpdates(locationCallback);
        }
    }

    private void checkLocationAndRequest() {
        // 检查位置服务是否开启
        LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        boolean isGpsEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
        boolean isNetworkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);

        if (!isGpsEnabled && !isNetworkEnabled) {
            // 位置服务未开启，引导用户开启
            Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
            startActivity(intent);
            return;
        }

        if (ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_FINE_LOCATION)
                != PackageManager.PERMISSION_GRANTED ||
                ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_COARSE_LOCATION)
                        != PackageManager.PERMISSION_GRANTED) {
            // 请求定位权限
            ActivityCompat.requestPermissions(MainActivity.this,
                    new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION},
                    LOCATION_PERMISSION_REQUEST_CODE);
            return;
        }

        requestLocationUpdates();
    }

    private void requestLocationUpdates() {
        // 先停止之前的位置更新请求
        if (fusedLocationClient != null) {
            fusedLocationClient.removeLocationUpdates(locationCallback);
        }

        // 使用新的定位请求构建方式
        LocationRequest locationRequest = new LocationRequest.Builder(Priority.PRIORITY_HIGH_ACCURACY, 10000)
                .setMinUpdateIntervalMillis(5000)
                .build();

        if (ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_FINE_LOCATION)
                == PackageManager.PERMISSION_GRANTED ||
                ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_COARSE_LOCATION)
                        == PackageManager.PERMISSION_GRANTED) {
            fusedLocationClient.requestLocationUpdates(locationRequest, locationCallback, null);
        }
    }

    // WGS - 84 转 BD - 09 坐标转换方法
    private double[] wgs84ToBd09(double wgLat, double wgLon) {
        double[] gcj02 = wgs84ToGcj02(wgLat, wgLon);
        return gcj02ToBd09(gcj02[0], gcj02[1]);
    }

    // WGS - 84 转 GCJ - 02 坐标转换方法
    private double[] wgs84ToGcj02(double wgLat, double wgLon) {
        if (outOfChina(wgLat, wgLon)) {
            return new double[]{wgLat, wgLon};
        }
        double dLat = transformLat(wgLon - 105.0, wgLat - 35.0);
        double dLon = transformLon(wgLon - 105.0, wgLat - 35.0);
        double radLat = wgLat / 180.0 * Math.PI;
        double magic = Math.sin(radLat);
        magic = 1 - 0.00669342162296594323 * magic * magic;
        double sqrtMagic = Math.sqrt(magic);
        dLat = (dLat * 180.0) / ((6378245.0 * (1 - 0.00669342162296594323)) / (magic * sqrtMagic) * Math.PI);
        dLon = (dLon * 180.0) / (6378245.0 / sqrtMagic * Math.cos(radLat) * Math.PI);
        double mgLat = wgLat + dLat;
        double mgLon = wgLon + dLon;
        return new double[]{mgLat, mgLon};
    }

    // GCJ - 02 转 BD - 09 坐标转换方法
    private double[] gcj02ToBd09(double ggLat, double ggLon) {
        double x = ggLon, y = ggLat;
        double z = Math.sqrt(x * x + y * y) + 0.00002 * Math.sin(y * Math.PI);
        double theta = Math.atan2(y, x) + 0.000003 * Math.cos(x * Math.PI);
        double bdLon = z * Math.cos(theta) + 0.0065;
        double bdLat = z * Math.sin(theta) + 0.006;
        return new double[]{bdLat, bdLon};
    }

    // 判断是否在中国境内
    private boolean outOfChina(double lat, double lon) {
        return (lon < 72.004 || lon > 137.8347) || (lat < 0.8293 || lat > 55.8271);
    }

    // 纬度转换辅助方法
    private double transformLat(double x, double y) {
        double ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * Math.sqrt(Math.abs(x));
        ret += (20.0 * Math.sin(6.0 * x * Math.PI) + 20.0 * Math.sin(2.0 * x * Math.PI)) * 2.0 / 3.0;
        ret += (20.0 * Math.sin(y * Math.PI) + 40.0 * Math.sin(y / 3.0 * Math.PI)) * 2.0 / 3.0;
        ret += (160.0 * Math.sin(y / 12.0 * Math.PI) + 320 * Math.sin(y * Math.PI / 30.0)) * 2.0 / 3.0;
        return ret;
    }

    // 经度转换辅助方法
    private double transformLon(double x, double y) {
        double ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * Math.sqrt(Math.abs(x));
        ret += (20.0 * Math.sin(6.0 * x * Math.PI) + 20.0 * Math.sin(2.0 * x * Math.PI)) * 2.0 / 3.0;
        ret += (20.0 * Math.sin(x * Math.PI) + 40.0 * Math.sin(x / 3.0 * Math.PI)) * 2.0 / 3.0;
        ret += (150.0 * Math.sin(x / 12.0 * Math.PI) + 300.0 * Math.sin(x / 30.0 * Math.PI)) * 2.0 / 3.0;
        return ret;
    }

    private boolean isNetworkAvailable() {
        ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
        if (connectivityManager != null) {
            NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
            return activeNetworkInfo != null && activeNetworkInfo.isConnected();
        }
        return false;
    }

    private void sendPostRequest(String deviceId, String latitude, String longitude) {
        if (!isNetworkAvailable()) {
            Log.e("API", "Network is not available, cannot send POST request");
            return;
        }
        Log.d("API", "Sending POST request with deviceId: " + deviceId + ", latitude: " + latitude + ", longitude: " + longitude);
        new Thread(() -> {
            OkHttpClient client = new OkHttpClient();

            // 构建 JSON 请求体
            JSONObject jsonBody = new JSONObject();
            try {
                jsonBody.put("deviceId", deviceId);
                jsonBody.put("latitude", latitude);
                jsonBody.put("longitude", longitude);
            } catch (JSONException e) {
                e.printStackTrace();
                new Handler(Looper.getMainLooper()).post(() -> {
                    Log.e("API", "Failed to build JSON request body: " + e.getMessage());
                });
                return;
            }

            RequestBody body = okhttp3.RequestBody.create(jsonBody.toString(), okhttp3.MediaType.parse("application/json"));

            Request request = new Request.Builder()
                    .url("http://47.92.209.179:9090/location/saveDeviceLocation")
                    .post(body)
                    .addHeader("Content-Type", "application/json")
                    .build();

            try {
                Response response = client.newCall(request).execute();
                int statusCode = response.code();
                String result = null;
                if (response.isSuccessful()) {
                    result = response.body().string();
                    Log.d("API", "POST request successful (Status Code: " + statusCode + "): " + result);
                } else {
                    result = response.body() != null ? response.body().string() : "No response body";
                    Log.e("API", "POST request failed (Status Code: " + statusCode + "): " + result);
                }
                final String finalResult = result;
                new Handler(Looper.getMainLooper()).post(() -> {
                    if (finalResult != null) {
                        if (statusCode >= 200 && statusCode < 300) {
                            Log.d("API", "POST request successful: " + finalResult);
                        } else {
                            Log.e("API", "POST request failed (Status Code: " + statusCode + "): " + finalResult);
                        }
                    } else {
                        Log.e("API", "POST request failed");
                    }
                });
            } catch (IOException e) {
                e.printStackTrace();
                new Handler(Looper.getMainLooper()).post(() -> {
                    Log.e("API", "POST request error: " + e.getMessage());
                });
            }
        }).start();
    }
}